package org.cloudplatform.common.feign.register;

import org.cloudplatform.common.feign.model.Instance;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 类描述： 一个抽象的 InstanceRegister 但是已经完成了 InstanceRegister 全部实现，
 * 如果需要自定义可以通过继承来完成自定义，他只是提供了一种实现而已
 * <p>
 * 作者：徐卫超 (cc)
 * 时间 2022/5/13 17:55
 */
public abstract class AbstractInstanceRegister implements InstanceRegister {

    private final Map<String, Map<String, Instance>> serviceInstanceMap = new ConcurrentHashMap<>();
    private final List<Instance> emptyList = new ArrayList<>();

    @Override
    public boolean register(Instance instance) {

        Map<String, Instance> instanceMap = serviceInstanceMap.computeIfAbsent(instance.getServiceId(), val -> new ConcurrentHashMap<>());
        instanceMap.put(instance.getInstanceId(), instance);
        return true;
    }

    @Override
    public boolean registerAll(List<Instance> instances) {

        serviceInstanceMap.clear();
        instances.forEach(instance -> {
            Map<String, Instance> instanceMap = serviceInstanceMap.computeIfAbsent(instance.getServiceId(), val -> new ConcurrentHashMap<>());
            instanceMap.put(instance.getInstanceId(), instance);
        });

        return true;
    }

    @Override
    public boolean remove(Instance instance) {
        Map<String, Instance> instanceMap = serviceInstanceMap.computeIfAbsent(instance.getServiceId(), val -> new ConcurrentHashMap<>());
        instanceMap.remove(instance.getInstanceId(), instance);
        return true;
    }

    @Override
    public boolean update(Instance instance) {
        return this.register(instance);
    }

    @Override
    public List<Instance> serviceInstance(String serviceId) {
        Map<String, Instance> instanceMap = serviceInstanceMap.get(serviceId);
        if (instanceMap != null) {
            return new ArrayList<>(instanceMap.values());
        }
        return emptyList;
    }

    @Override
    public boolean removeServiceName(String serviceName) {
        serviceInstanceMap.remove(serviceName);
        return true;
    }

    @Override
    public boolean updateServiceName(String serviceName, List<Instance> instances) {
        ConcurrentHashMap<String, Instance> newMap = new ConcurrentHashMap<>();
        for (Instance instance : instances) {
            newMap.put(instance.getServiceId(), instance);
        }
        serviceInstanceMap.put(serviceName, newMap);
        return true;
    }

    public Set<String> serviceNames() {
        return serviceInstanceMap.keySet();
    }
}
